﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using MongoDB.Driver;
using MongoDB.Driver.Builders;
using MongoDB.Driver.Linq;
using MongoDB.Bson;
using System.Net.Mail;
using SpyApp.Models.BaseCommon.MSG_STR;
using SpyApp.Models.BaseCommon;
using SpyApp.Models.EntytiRepossitory;
using SpyApp.Models.BaseCommon.Enum;

using System.Net;
using System.Text;
using System.IO;
using System.Security.Cryptography.X509Certificates;
using System.Net.Security;
using System.Collections.Specialized;


namespace SpyApp.Models
{
    public class UserRepository : IUserRepository
    {

        SafeSystemContext ctx = new SafeSystemContext();     
        //Constructor
        public UserRepository()
        {
            if (SafeSystemContext.ServerIsDown)
            {
                var _roles = ctx.Roles.FindAs(typeof(Roles), Query.NE("_id", "null"));
                if (_roles.Count() < 3)
                    InitializationRoles();
            }
        }
        //Tao roles
        private void InitializationRoles()
        {
            BsonDocument[] roles = {
                                        new BsonDocument {
                                        { "Id", "1" },
                                        { "RoleName", "Admin" },
                                        { "Status", DBEntity.ObjectStatus.Active },
                                        { "CreateBy", "1" },
                                        { "CreateDate", DateTime.UtcNow},
                                        { "LastUpdateBy", "1" },
                                        { "LastUpdateDate", DateTime.UtcNow}
                                        },
                                        new BsonDocument {
                                        { "Id", "2" },
                                        { "RoleName", "System" },
                                        { "Status", DBEntity.ObjectStatus.Active },
                                        { "CreateBy", "1" },
                                        { "CreateDate", DateTime.UtcNow},
                                        { "LastUpdateBy", "1" },
                                        { "LastUpdateDate", DateTime.UtcNow}
                                        },
                                        new BsonDocument {
                                        { "Id", "3" },
                                        { "RoleName", "User" },
                                        { "Status", DBEntity.ObjectStatus.Active },
                                        { "CreateBy", "1" },
                                        { "CreateDate", DateTime.UtcNow},
                                        { "LastUpdateBy", "1" },
                                        { "LastUpdateDate", DateTime.UtcNow}
                                        }
                                      };
            ctx.Roles.InsertBatch(roles);            
        }
        //Tao user in roles
        private void InitializationUserInRoles()
        {
            BsonDocument[] userInRoles = {
                                        new BsonDocument {
                                        { "userId", "1" },
                                        { "rolesId", "Admin" },
                                        { "Status", DBEntity.ObjectStatus.Active },
                                        { "CreateBy", "1" },
                                        { "CreateDate", DateTime.UtcNow},
                                        { "LastUpdateBy", "1" },
                                        { "LastUpdateDate", DateTime.UtcNow}
                                        },
                                        new BsonDocument {
                                        { "userId", "2" },
                                        { "rolesId", "System" },
                                        { "Status", DBEntity.ObjectStatus.Active },
                                        { "CreateBy", "1" },
                                        { "CreateDate", DateTime.UtcNow},
                                        { "LastUpdateBy", "1" },
                                        { "LastUpdateDate", DateTime.UtcNow}
                                        }                                       
                                      };
            ctx.UserInRoles.InsertBatch(userInRoles);     
        }

        public string SendMail(string subject, string body, string to, bool isHtml, bool isSSL)
        {
            try
            {
                using (MailMessage mail = new MailMessage())
                {
                    mail.From = new MailAddress(Properties.Settings.Default.EmailAddress.ToString(), Properties.Settings.Default.EmailTitle.ToString());
                    mail.To.Add(to);
                    mail.Subject = subject;
                    mail.Body = body;
                    mail.IsBodyHtml = isHtml;
                    mail.Priority = MailPriority.High;

                    SmtpClient client = new SmtpClient();
                    client.Host = Properties.Settings.Default.EmailHost;
                    client.Port = 587;         
                    client.EnableSsl = true;
                    client.DeliveryMethod = SmtpDeliveryMethod.Network;
                    client.UseDefaultCredentials = false;
                    client.Credentials = new System.Net.NetworkCredential(Properties.Settings.Default.EmailAddress.ToString(), Properties.Settings.Default.EmailPassword.ToString());                    
                    client.Send(mail);
                    
                }
            }
            catch (SmtpException ex)
            {
                return ex.Message;
            }
            return BaseCommon.MSG_STR.AUTH_MESSAGE_STRING.SENDMAIL_SUCCESSFUL ;
        }

        public string CreateActivationCode(string userName)
        {
            string strString = "abcdefghijklmnopqrstuvwxyz0123456789";
            Random random = new Random();
            int randomCharIndex = 0;
            char randomChar;
            string activationCode = "";
            string confirmCode = "";
            for (int i = 0; i < 4; i++)
            {
                randomCharIndex = random.Next(0, strString.Length);
                randomChar = strString[randomCharIndex];
                confirmCode += Convert.ToString(randomChar);
            }
            activationCode = BaseCommon.EncryptionUtil.Encode(confirmCode, userName);
            return activationCode;
        }

        public User VerifyUser(string activationCode)
        {
            if (string.IsNullOrEmpty(activationCode))
                throw new ArgumentNullException("ActivationCode", "User Activation Code is empty!");
            var _user = (User)ctx.Users.FindOneAs(typeof(User), Query.EQ("ActiveInvationCode", activationCode));
            return _user;            
        }

        public BaseCommon.ERROR_CODE.ERROR_CODE_USER_VERIFY VerifyUser(string activationCode, ref string _messageSystemError, ref  User user)
        {
            try
            {
                if (SafeSystemContext.ServerIsDown)
                    throw new ExeptionUtils.CustomException(BaseCommon.MSG_STR.AUTH_MESSAGE_STRING.SERVER_IS_DOWN);
                if (string.IsNullOrEmpty(activationCode))
                    throw new ArgumentNullException("ActivationCode", "User Activation Code is empty!");
                var _user = (User)ctx.Users.FindOneAs(typeof(User), Query.EQ("ActiveInvationCode", activationCode));
                if (_user != null)
                {
                    user = _user;
                    return BaseCommon.ERROR_CODE.ERROR_CODE_USER_VERIFY.SUCCESS;
                }
                else
                {
                    return BaseCommon.ERROR_CODE.ERROR_CODE_USER_VERIFY.DO_NOT_EXIST;
                }
            }
            catch (Exception ex)
            {
                _messageSystemError = BaseCommon.ExeptionUtils.ExceptionToMessage(ex);
                return BaseCommon.ERROR_CODE.ERROR_CODE_USER_VERIFY.SYSTEM_ERROR;
            }
        }

        #region USER

        private List<User> userList = new List<User>();
        
        public IEnumerable<User> GetAllUser()
        {
            if (SafeSystemContext.ServerIsDown)
                return null;
            var _user = ctx.Users.FindAs(typeof(User),Query.NE("_id","null"));
            if(_user.Count()>0)
            {
                userList.Clear();
                foreach (User u in _user)
                    userList.Add(u);                
            }
            var result = userList.AsQueryable();
            return result;            
        }

        public BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT GetAllUser(ref string _messageSystemError, ref  IEnumerable<User> list)
        {
            try
            {
                if (SafeSystemContext.ServerIsDown)
                    throw new ExeptionUtils.CustomException(BaseCommon.MSG_STR.AUTH_MESSAGE_STRING.SERVER_IS_DOWN);              
                var _user = ctx.Users.FindAs(typeof(User), Query.NE("_id", "null"));
                if (_user.Count() > 0)
                {
                    userList.Clear();
                    foreach (User u in _user)
                        userList.Add(u);
                }
                var result = userList.AsQueryable();
                list = result.ToList();
                return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT.SUCCESS;
            }
            catch (Exception ex)
            {
                _messageSystemError = BaseCommon.ExeptionUtils.ExceptionToMessage(ex);
                return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT.SYSTEM_ERROR;
            }
        }

        public User GetUserById(string id)
        { 
            if(string.IsNullOrEmpty(id))
                throw new ArgumentNullException("id", AUTH_MESSAGE_STRING.EMPTY_USERID);
            var _user = (User)ctx.Users.FindOneAs(typeof(User),Query.EQ("_id",id));

            return _user;
        }

        public BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_GET_BY_ID GetUserById(string id, ref string _messageSystemError, ref User user)
        {
            try
            {                
                if (SafeSystemContext.ServerIsDown)
                    throw new ExeptionUtils.CustomException(BaseCommon.MSG_STR.AUTH_MESSAGE_STRING.SERVER_IS_DOWN);
                if (string.IsNullOrEmpty(id))
                    throw new ArgumentNullException("id", AUTH_MESSAGE_STRING.EMPTY_USERID);
                var _user = (User)ctx.Users.FindOneAs(typeof(User), Query.EQ("_id", id));
                user = _user;
                return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_GET_BY_ID.SUCCESS;
            }
            catch (Exception ex)
            { 
                _messageSystemError = BaseCommon.ExeptionUtils.ExceptionToMessage(ex);
                return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_GET_BY_ID.SYSTEM_ERROR;
            
            }
        }

        public User GetByUserName(string username)
        {
            if (string.IsNullOrEmpty(username))
                throw new ArgumentNullException("UserName", AUTH_MESSAGE_STRING.EMPTY_USERNAME);
            var _user = (User)ctx.Users.FindOneAs(typeof(User), Query.EQ("UserName", username));
            //var _role = (Roles)ctx.Roles.FindOneAs(typeof(Roles), Query.EQ("Id", "1"));
            return _user;
            //return null;
        }

        public BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT GetByUserName(string username, ref string _messageSystemError, ref User user)
        {
            try
            {
                if (SafeSystemContext.ServerIsDown)
                    throw new ExeptionUtils.CustomException(BaseCommon.MSG_STR.AUTH_MESSAGE_STRING.SERVER_IS_DOWN);
                if (string.IsNullOrEmpty(username))
                    throw new ArgumentNullException("UserName", AUTH_MESSAGE_STRING.EMPTY_USERNAME);
                var _user = (User)ctx.Users.FindOneAs(typeof(User), Query.EQ("UserName", username));
                //var _role = (Roles)ctx.Roles.FindOneAs(typeof(Roles), Query.EQ("Id", "1"));
                user = _user;
                return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT.SUCCESS;
            }
            catch (Exception ex)
            {
                _messageSystemError = BaseCommon.ExeptionUtils.ExceptionToMessage(ex);
                return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT.SYSTEM_ERROR;
            }
            
        }      
        
        //Mobile control used
        public User RegisterNewUser(User user)
        {
            try
            {
                if (String.IsNullOrEmpty(user.UserName) || String.IsNullOrEmpty(user.PassWord))
                    throw new ExeptionUtils.CustomException(BaseCommon.MSG_STR.AUTH_MESSAGE_STRING.UNVALID_REGISTER_USER);
                if (IsExistUserName(user.UserName))
                    throw new ExeptionUtils.CustomException(BaseCommon.MSG_STR.AUTH_MESSAGE_STRING.DUPLICATE_USERNAME);
                user.Id = Guid.NewGuid().ToString();
                user.PassWord = BaseCommon.EncryptionUtil.Encode(user.PassWord, user.UserName.Trim().ToLower());
                user.ActiveInvationCode = CreateActivationCode(user.UserName);                
                //Gửi mail xác nhận
                string subject = "Confirmation of Registration";
                string body = "Please activate your account by going to the followin URL: \n";
                body += "http://localhost:11326/api/user/"+ user.ActiveInvationCode.ToString();
                //if (SendMail(subject, body, user.UserName.ToString(), true, true) != "Send email successful!")
                //{
                    
                    //throw new BaseCommon.CustomException(BaseCommon.MSG_STR.AUTH_MESSAGE_STRING.SENDMAIL_ERROR);
                //}
                SendMail(subject, body, user.UserName.ToString(), true, true);
                ctx.Users.Insert(user);
                return user;
            }
            catch(Exception ex)
            {
                throw ExeptionUtils.ThrowCustomException(ex);                
            }
        }

        public BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_ADDNEW RegisterNewUser(User _user, ref string _messageSystemError, ref User user)
        {
            try
            {
                if (SafeSystemContext.ServerIsDown)
                    throw new ExeptionUtils.CustomException(BaseCommon.MSG_STR.AUTH_MESSAGE_STRING.SERVER_IS_DOWN);
                if (String.IsNullOrEmpty(_user.UserName) || String.IsNullOrEmpty(_user.PassWord))
                    throw new ExeptionUtils.CustomException(BaseCommon.MSG_STR.AUTH_MESSAGE_STRING.UNVALID_REGISTER_USER);
                if (IsExistUserName(_user.UserName))
                    throw new ExeptionUtils.CustomException(BaseCommon.MSG_STR.AUTH_MESSAGE_STRING.DUPLICATE_USERNAME);
                _user.Id = Guid.NewGuid().ToString();
                _user.PassWord = BaseCommon.EncryptionUtil.Encode(_user.PassWord, _user.UserName.Trim().ToLower());
                _user.ActiveInvationCode = CreateActivationCode(_user.UserName);
                //Gửi mail xác nhận
                string subject = "Confirmation of Registration";
                string body = "Please activate your account by going to the followin URL: \n";
                body += "http://localhost:11326/api/user/" + _user.ActiveInvationCode.ToString();
                //if (SendMail(subject, body, user.UserName.ToString(), true, true) != "Send email successful!")
                //{

                //throw new BaseCommon.CustomException(BaseCommon.MSG_STR.AUTH_MESSAGE_STRING.SENDMAIL_ERROR);
                //}
                SendMail(subject, body, _user.UserName.ToString(), true, true);
                ctx.Users.Insert(_user);
                user = _user;
                return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_ADDNEW.SUCCESS;
            }
            catch (Exception ex)
            {
                _messageSystemError = BaseCommon.ExeptionUtils.ExceptionToMessage(ex);
                return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_ADDNEW.SYSTEM_ERROR;
            }
        }

        //Account control used
        public User AddNewAccount(AccountModel.RegisterModel model, ref string _messageError)
        {
            try
            {
                if (String.IsNullOrEmpty(model.Email) || String.IsNullOrEmpty(model.Password))
                {
                    _messageError = BaseCommon.MSG_STR.AUTH_MESSAGE_STRING.UNVALID_REGISTER_USER;
                    throw new ExeptionUtils.CustomException(BaseCommon.MSG_STR.AUTH_MESSAGE_STRING.UNVALID_REGISTER_USER);
                }
                if (IsExistUserName(model.Email))
                {
                    _messageError = BaseCommon.MSG_STR.AUTH_MESSAGE_STRING.DUPLICATE_USERNAME;
                    throw new ExeptionUtils.CustomException(BaseCommon.MSG_STR.AUTH_MESSAGE_STRING.DUPLICATE_USERNAME);
                }
                var _role = GetRoleById("3");
                User user = new User();
                user.Id = Guid.NewGuid().ToString();
                user.UserInRoles = new List<Roles>();
                user.UserInRoles.Add(_role);
                user.UserName = model.Email;
                user.PassWord = BaseCommon.EncryptionUtil.Encode(model.Password, model.Email.Trim().ToLower());
                user.ActiveInvationCode = CreateActivationCode(model.Email);        
                ctx.Users.Insert(user);
                return user;
            }
            catch (Exception ex)
            {
                throw ExeptionUtils.ThrowCustomException(ex);
            }
        }

        public BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_ADDNEW AddNewAccount(AccountModel.RegisterModel model, ref string _messageSystemError, ref User user)
        {
            try
            {
                if (SafeSystemContext.ServerIsDown)
                    throw new ExeptionUtils.CustomException(BaseCommon.MSG_STR.AUTH_MESSAGE_STRING.SERVER_IS_DOWN);
                if (String.IsNullOrEmpty(model.Email) || String.IsNullOrEmpty(model.Password))
                {
                    _messageSystemError = BaseCommon.MSG_STR.AUTH_MESSAGE_STRING.UNVALID_REGISTER_USER;
                    throw new ExeptionUtils.CustomException(BaseCommon.MSG_STR.AUTH_MESSAGE_STRING.UNVALID_REGISTER_USER);
                }
                if (IsExistUserName(model.Email))
                {
                    _messageSystemError = BaseCommon.MSG_STR.AUTH_MESSAGE_STRING.DUPLICATE_USERNAME;
                    throw new ExeptionUtils.CustomException(BaseCommon.MSG_STR.AUTH_MESSAGE_STRING.DUPLICATE_USERNAME);
                }
                User _user = new User();
                _user.Id = Guid.NewGuid().ToString();
                _user.UserName = model.Email;
                _user.PassWord = BaseCommon.EncryptionUtil.Encode(model.Password, model.Email.Trim().ToLower());
                _user.ActiveInvationCode = CreateActivationCode(model.Email);
                ctx.Users.Insert(_user);
                user = _user;                
                return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_ADDNEW.SUCCESS;
            }
            catch (Exception ex)
            {                
                _messageSystemError = BaseCommon.ExeptionUtils.ExceptionToMessage(ex);
                return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_ADDNEW.SYSTEM_ERROR;
            }
        }

        public User Login(string userName, string passWord)
        {
            try
            {   if(SafeSystemContext.ServerIsDown)
                    throw new ExeptionUtils.CustomException(BaseCommon.MSG_STR.AUTH_MESSAGE_STRING.SERVER_IS_DOWN);
                if (string.IsNullOrEmpty(userName) || string.IsNullOrEmpty(passWord))
                    throw new ExeptionUtils.CustomException(BaseCommon.MSG_STR.AUTH_MESSAGE_STRING.UNVALID_REGISTER_USER);
                string encodePassword = BaseCommon.EncryptionUtil.Encode(passWord, userName.Trim().ToLower());
                User user = (User)ctx.Users.FindOneAs<User>(Query.EQ("UserName", userName));
                if (user != null)
                {
                    if (user.UserStatus != BaseCommon.Enum.DBEntity.UserStatus.Active)
                        throw new ExeptionUtils.CustomException(BaseCommon.MSG_STR.AUTH_MESSAGE_STRING.USER_NOT_ACTIVATED);
                    if (user.PassWord != encodePassword)
                        throw new ExeptionUtils.CustomException(BaseCommon.MSG_STR.AUTH_MESSAGE_STRING.UNVALID_LOGIN_USER);
                    return user;
                }
                else                   
                    throw new ExeptionUtils.CustomException(BaseCommon.MSG_STR.AUTH_MESSAGE_STRING.UNVALID_LOGIN_USER);
            }
            catch (Exception ex)
            {
                throw ExeptionUtils.ThrowCustomException(ex);
            }
        }

        public BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT Login(string userName, string passWord, ref string _messageSystemError, ref User user)
        {
            try
            {
                if (SafeSystemContext.ServerIsDown)
                    throw new ExeptionUtils.CustomException(BaseCommon.MSG_STR.AUTH_MESSAGE_STRING.SERVER_IS_DOWN);
                if (SafeSystemContext.ServerIsDown)
                    throw new ExeptionUtils.CustomException(BaseCommon.MSG_STR.AUTH_MESSAGE_STRING.SERVER_IS_DOWN);
                if (string.IsNullOrEmpty(userName) || string.IsNullOrEmpty(passWord))
                    throw new ExeptionUtils.CustomException(BaseCommon.MSG_STR.AUTH_MESSAGE_STRING.UNVALID_REGISTER_USER);
                string encodePassword = BaseCommon.EncryptionUtil.Encode(passWord, userName.Trim().ToLower());
                User _user = (User)ctx.Users.FindOneAs<User>(Query.EQ("UserName", userName));
                if (_user != null)
                {
                    if (_user.UserStatus != BaseCommon.Enum.DBEntity.UserStatus.Active)
                        throw new ExeptionUtils.CustomException(BaseCommon.MSG_STR.AUTH_MESSAGE_STRING.USER_NOT_ACTIVATED);
                    if (_user.PassWord != encodePassword)
                        throw new ExeptionUtils.CustomException(BaseCommon.MSG_STR.AUTH_MESSAGE_STRING.UNVALID_LOGIN_USER);
                    user = _user;
                    return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT.SUCCESS;
                }
                else
                    throw new ExeptionUtils.CustomException(BaseCommon.MSG_STR.AUTH_MESSAGE_STRING.UNVALID_LOGIN_USER);
            }
            catch (Exception ex)
            {
                _messageSystemError = BaseCommon.ExeptionUtils.ExceptionToMessage(ex);
                return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT.SYSTEM_ERROR;
            }
        }      

        public bool Update(string id, User user)
        {         
            var _user = (User)ctx.Users.FindOneAs(typeof(User), Query.EQ("_id", user.Id));
            if (_user != null)
            {
                if (_user.UserInRoles != null)
                    _user.UserInRoles.Clear();
                else
                    _user.UserInRoles = new List<Roles>();
                foreach (Roles r in user.UserInRoles)
                    _user.UserInRoles.Add(r);
                ctx.Users.Save(_user);
                var query = Query<User>.EQ(e => e.Id, user.Id);
                var update = Update<User>.Set(e => e.RememberMe, user.RememberMe)
                                         .Set(e => e.ActiveInvationCode, user.ActiveInvationCode)
                                         .Set(e => e.Age, user.Age)
                                         .Set(e => e.TotalLogin, user.TotalLogin)
                                         .Set(e => e.UserStatus, user.UserStatus)
                                         .Set(e => e.Status, user.Status)
                                         .Set(e => e.UserType, user.UserType)
                                         .Set(e => e.UserInRoles, user.UserInRoles);
                ctx.Users.Update(query, update);
                return true;
            }
            else
                return false;
        }      

        public BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_UPDATE Update(string id, User user, ref string _messageSystemError)
        {
            try
            {
                if (SafeSystemContext.ServerIsDown)
                    throw new ExeptionUtils.CustomException(BaseCommon.MSG_STR.AUTH_MESSAGE_STRING.SERVER_IS_DOWN);
                var _user = (User)ctx.Users.FindOneAs(typeof(User), Query.EQ("_id", user.Id));
                if (_user != null)
                {
                    if (_user.UserInRoles != null)
                        _user.UserInRoles.Clear();
                    else
                        _user.UserInRoles = new List<Roles>();
                    // lỗi : user.UserInRoles = null
                    if (user.UserInRoles != null)
                    {
                        foreach (Roles r in user.UserInRoles)
                            _user.UserInRoles.Add(r);
                    }
                    ctx.Users.Save(_user);
                    var query = Query<User>.EQ(e => e.Id, user.Id);
                    var update = Update<User>.Set(e => e.RememberMe, user.RememberMe)
                                             .Set(e => e.ActiveInvationCode, user.ActiveInvationCode)
                                             .Set(e => e.Age, user.Age)
                                             .Set(e => e.TotalLogin, user.TotalLogin)
                                             .Set(e => e.UserStatus, user.UserStatus)
                                             .Set(e => e.Status, user.Status)
                                             .Set(e => e.UserType, user.UserType)
                                             .Set(e => e.UserInRoles, user.UserInRoles);
                    ctx.Users.Update(query, update);
                    return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_UPDATE.SUCCESS;
                }
                else
                    return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_UPDATE.EXIT_DATA;
            }
            catch (Exception ex)
            { 
                _messageSystemError = BaseCommon.ExeptionUtils.ExceptionToMessage(ex);
                return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_UPDATE.SYSTEM_ERROR;
            }            
        }

        public bool Delete(string id)
        {            
            var _user = (User)ctx.Users.FindOneAs(typeof(User),Query.EQ("_id",id.ToString()));
            _user.Status =  BaseCommon.Enum.DBEntity.ObjectStatus.DeActivated;
            _user.LastModifined = DateTime.UtcNow;
            ctx.Users.Save(_user);
            return true;            
        }

        public BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_DELETE Delete(string id, ref string _messageSystemError)
        {
            try
            {
                if (SafeSystemContext.ServerIsDown)
                    throw new ExeptionUtils.CustomException(BaseCommon.MSG_STR.AUTH_MESSAGE_STRING.SERVER_IS_DOWN);
                var _user = (User)ctx.Users.FindOneAs(typeof(User), Query.EQ("_id", id.ToString()));
                _user.Status = BaseCommon.Enum.DBEntity.ObjectStatus.DeActivated;
                _user.LastModifined = DateTime.UtcNow;
                ctx.Users.Save(_user);
                return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_DELETE.SUCCESS;
            }
            catch (Exception ex)
            {
                _messageSystemError = BaseCommon.ExeptionUtils.ExceptionToMessage(ex);
                return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_DELETE.SYSTEM_ERROR;
            }
        }
        
        public bool UserIsValid(User user)
        {
            throw new NotImplementedException();
        }

        public bool IsExistUserName(string userName)
        {
            try
            {            
                var result = from u in ctx.Users.AsQueryable<User>()
                             where u.UserName == userName 
                             select u;
                if (result.Count() > 0)
                    return true;               
                else                
                    return false;           
            }
            catch (Exception ex)
            {
                throw BaseCommon.ExeptionUtils.ThrowCustomException(ex);

            }
        }

        public BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_CHECK_DUPPLICATE IsExistUserName(string userName, ref string _messageSystemError)
        {
            try
            {
                if (SafeSystemContext.ServerIsDown)
                    throw new ExeptionUtils.CustomException(BaseCommon.MSG_STR.AUTH_MESSAGE_STRING.SERVER_IS_DOWN);
                var result = from u in ctx.Users.AsQueryable<User>()
                             where u.UserName == userName
                             select u;
                if (result.Count() > 0)
                    return  BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_CHECK_DUPPLICATE.EXISTED;
                else
                    return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_CHECK_DUPPLICATE.NOT_EXISTED;
            }
            catch (Exception ex)
            {
                _messageSystemError = BaseCommon.ExeptionUtils.ExceptionToMessage(ex);
                return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_CHECK_DUPPLICATE.SYSTEM_ERROR;

            }
        }

        public void ChangePassWord(string user, string currentPassWord, string newPassWord)
        {
            throw new NotImplementedException();
        }
        
        #endregion
        
        #region MESSAGE

        //public Message AddNewMassage_(Message msg, string userId)
        //{         
        //    //var _user = (User)ctx.Users.FindOneAs(typeof(User), Query.EQ("_id", userId));
        //    //if (_user != null)
        //    //{
        //    //    if (_user.TotalDeviceRegisted. .Messages == null)                
        //    //        _user.Messages = new List<Message>();
        //    //    _user.Messages.Add(msg);
        //    //    ctx.Users.Save(_user);
        //    //    //ctx.Messages.Insert(message);
        //    //    return msg;
        //    //}
        //    //else
        //        return null;
        //}

        public IEnumerable<Message> GetAllMessageForDeviceByUser(string deviceId,string userId)
        {
            List<Message> _msg = new List<Message>();
            using (ctx.Database.Server.RequestStart(ctx.Database))
            {
                Device _device = GetDeviceById(deviceId, userId);
                return _device.Messages;        
            }

        }

        public BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT GetAllMessageForDeviceByUser(string deviceId, string userId, ref string _messageSystemError, ref  IEnumerable<Message> list)
        {
            try
            {
                if (SafeSystemContext.ServerIsDown)
                    throw new ExeptionUtils.CustomException(BaseCommon.MSG_STR.AUTH_MESSAGE_STRING.SERVER_IS_DOWN);
                using (ctx.Database.Server.RequestStart(ctx.Database))
                {
                    Device _device = GetDeviceById(deviceId, userId);
                    list = _device.Messages.ToList();
                    return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT.SUCCESS;
                }
            }
            catch (Exception ex)
            {
                _messageSystemError = BaseCommon.ExeptionUtils.ExceptionToMessage(ex);
                return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT.SYSTEM_ERROR;
            }
        }

        public bool CheckingMessageExists(string deviceId, string userId , string _uuid)
        {            
            List<Message> _msg = new List<Message>();
            using (ctx.Database.Server.RequestStart(ctx.Database))
            {
                Device _device = GetDeviceById(deviceId, userId);
                return  _device.Messages.Find(m => m.Uuid.Equals(_uuid)) == null ? false : true;
                //_msg = _device.Messages;            
                
                //Message msg = (from m in _device.Messages
                //          where m.Uuid == _uuid
                //          select m).Single<Message>();            
            }
            
        }        

        #endregion Message

        #region Location

        public BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT GetAllLocationForDeviceByUser(string deviceId, string userId, ref string _messageSystemError, ref  IEnumerable<Location> list)
        {
            try
            {
                if (SafeSystemContext.ServerIsDown)
                    throw new ExeptionUtils.CustomException(BaseCommon.MSG_STR.AUTH_MESSAGE_STRING.SERVER_IS_DOWN);                
                using (ctx.Database.Server.RequestStart(ctx.Database))
                {
                    Device _device = GetDeviceById(deviceId, userId);
                    list = _device.LocationTracking.ToList();
                    return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT.SUCCESS;
                }
            }
            catch (Exception ex)
            {
                _messageSystemError = BaseCommon.ExeptionUtils.ExceptionToMessage(ex);
                return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT.SYSTEM_ERROR;
            }
        }

        public bool GetAllLocationFormDateToDateForDeviceByUser(string deviceId, DateTime formDate, DateTime toDate, string userId)
        {
            try
            {
                if (SafeSystemContext.ServerIsDown)
                    throw new ExeptionUtils.CustomException(BaseCommon.MSG_STR.AUTH_MESSAGE_STRING.SERVER_IS_DOWN);
                List<Location> _list = new  List<Location>() ;
                using (ctx.Database.Server.RequestStart(ctx.Database))
                {
                    Device _device = GetDeviceById(deviceId, userId);                                       
                    DateTime _todate = toDate.AddDays(1);
                    //list = _device.LocationTracking.ToList();
                    _list = _device.LocationTracking.Where(e => e.DateTimeCheck.CompareTo(formDate) == 1 && e.DateTimeCheck.CompareTo(_todate) == -1).ToList();
                    return true;
                }
            }
            catch (Exception ex)
            {

                return false;
            }
        }      

        public BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT GetAllLocationFormDateToDateForDeviceByUser(string deviceId, DateTime formDate, DateTime toDate, string userId, ref string _messageSystemError, ref  IEnumerable<Location> list)
        {
            try
            {
                if (SafeSystemContext.ServerIsDown)
                    throw new ExeptionUtils.CustomException(BaseCommon.MSG_STR.AUTH_MESSAGE_STRING.SERVER_IS_DOWN);
                using (ctx.Database.Server.RequestStart(ctx.Database))
                {
                    Device _device = GetDeviceById(deviceId, userId);
                    DateTime _todate = toDate.AddDays(1);
                    
                    
                    //list = _device.LocationTracking.ToList();
                    list = _device.LocationTracking.Where(e => e.DateTimeCheck.CompareTo(formDate) == 1 && e.DateTimeCheck.CompareTo(_todate) == -1).ToList();
                    return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT.SUCCESS;
                }
            }
            catch (Exception ex)
            {
                _messageSystemError = BaseCommon.ExeptionUtils.ExceptionToMessage(ex);
                return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT.SYSTEM_ERROR;
            }
        }        

        #endregion Location

        #region DEVICE

        public Device AddNewDevice(Device device, string userId)
        {
            var _user = (User)ctx.Users.FindOneAs(typeof(User), Query.EQ("_id", userId));
            if (_user != null)
            {
                if (_user.SnDeviceRegisted == null)
                    _user.SnDeviceRegisted = new List<Device>();
                _user.SnDeviceRegisted.Add(device);
                ctx.Users.Save(_user);
                return device;
            }
            else
                return null;
        }

        public BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_ADDNEW AddNewDevice(Device _device, string userId, ref string _messageSystemError, ref Device device)
        {
            try
            {
                if (SafeSystemContext.ServerIsDown)
                    throw new ExeptionUtils.CustomException(BaseCommon.MSG_STR.AUTH_MESSAGE_STRING.SERVER_IS_DOWN);
                var _user = (User)ctx.Users.FindOneAs(typeof(User), Query.EQ("_id", userId));
                if (_user != null)
                {
                    if (_user.SnDeviceRegisted == null)
                        _user.SnDeviceRegisted = new List<Device>();
                    _user.SnDeviceRegisted.Add(_device);
                    ctx.Users.Save(_user);
                    device = _device;
                    return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_ADDNEW.SUCCESS;
                }
                else
                    return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_ADDNEW.EXIT_DATA;
            }
            catch (Exception ex)
            {
                _messageSystemError = BaseCommon.ExeptionUtils.ExceptionToMessage(ex);
                return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_ADDNEW.SYSTEM_ERROR;
            }
        }     
        
        public bool UpdateDeviceBySerial(string sn, Device dv, string userId)
        {
            Device _dv = new Device();
            var _user = (User)ctx.Users.FindOneAs(typeof(User), Query.EQ("_id", userId));
            if (_user != null)
            {
                if (_user.SnDeviceRegisted.Find(d => d.Sn.Equals(dv.Sn.ToString())) != null)  
                { 
                  ctx.Users.Update(Query.EQ("SnDeviceRegisted.Id", dv.Id), MongoDB.Driver.Builders.Update.Set("SnDeviceRegisted.$" ,BsonDocumentWrapper.Create<Device>(dv)));
                  return true;
                }
                else
                    return false;
                //_dv = _user.SnDeviceRegisted.Find(d => d.Sn == dv.Sn);            
            }
            else
                return false;
        }

        public BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_UPDATE UpdateDeviceBySerial(string sn, Device dv, string userId, ref string _messageSystemError)
        {
            try
            {
                if (SafeSystemContext.ServerIsDown)
                    throw new ExeptionUtils.CustomException(BaseCommon.MSG_STR.AUTH_MESSAGE_STRING.SERVER_IS_DOWN);
                Device _dv = new Device();
                var _user = (User)ctx.Users.FindOneAs(typeof(User), Query.EQ("_id", userId));
                if (_user != null)
                {
                    if (_user.SnDeviceRegisted.Find(d => d.Sn.Equals(dv.Sn.ToString())) != null)
                    {
                        ctx.Users.Update(Query.EQ("SnDeviceRegisted.Id", dv.Id), MongoDB.Driver.Builders.Update.Set("SnDeviceRegisted.$", BsonDocumentWrapper.Create<Device>(dv)));
                        return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_UPDATE.SUCCESS;
                    }
                    else
                        return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_UPDATE.EXIT_DATA;
                    //_dv = _user.SnDeviceRegisted.Find(d => d.Sn == dv.Sn);            
                }
                else
                    return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_UPDATE.EXIT_DATA;
            }
            catch (Exception ex)
            {
                _messageSystemError = BaseCommon.ExeptionUtils.ExceptionToMessage(ex);
                return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_UPDATE.SYSTEM_ERROR;
            }
        }

        public IEnumerable<Device> GetAllDeviceByUser(string userId)
        {
            List<Device> _devices = new List<Device>();
            using (ctx.Database.Server.RequestStart(ctx.Database))
            {
                var _user = (User)ctx.Users.FindOneAs(typeof(User), Query.EQ("_id", userId));
                if (_user != null)
                {
                    _devices = _user.SnDeviceRegisted;
                    return _devices;
                }
                else
                    return null;
            }
        }

        public BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT GetAllDeviceByUser(string userId, ref string _messageSystemError, ref  IEnumerable<Device> list)
        {
            try
            {
                if (SafeSystemContext.ServerIsDown)
                    throw new ExeptionUtils.CustomException(BaseCommon.MSG_STR.AUTH_MESSAGE_STRING.SERVER_IS_DOWN);
                List<Device> _devices = new List<Device>();
                using (ctx.Database.Server.RequestStart(ctx.Database))
                {
                    var _user = (User)ctx.Users.FindOneAs(typeof(User), Query.EQ("_id", userId));
                    if (_user != null)
                    {
                        _devices = _user.SnDeviceRegisted;
                        list = _devices.ToList();
                        return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT.SUCCESS;
                    }
                    else
                        return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT.DO_NOT_EXIST;
                }
            }
            catch (Exception ex)
            {
                _messageSystemError = BaseCommon.ExeptionUtils.ExceptionToMessage(ex);
                return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT.SYSTEM_ERROR;
            }
        }        
        
        public IEnumerable<Device> GetListDeviceByUserName(string username)
        {
            List<Device> _devices = new List<Device>();
            using (ctx.Database.Server.RequestStart(ctx.Database))
            {
                var _user = (User)ctx.Users.FindOneAs(typeof(User), Query.EQ("UserName", username));
                if (_user != null)
                {
                    _devices = _user.SnDeviceRegisted;
                    if (_devices == null)
                        _devices = new List<Device>();
                    return _devices;
                }
                else
                    return null;
            }
        }

        public BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT GetListDeviceByUserName(string username,  ref string _messageSystemError, ref  IEnumerable<Device> list)
        {
            try
            {
                if (SafeSystemContext.ServerIsDown)
                    throw new ExeptionUtils.CustomException(BaseCommon.MSG_STR.AUTH_MESSAGE_STRING.SERVER_IS_DOWN);
                List<Device> _devices = new List<Device>();
                using (ctx.Database.Server.RequestStart(ctx.Database))
                {
                    var _user = (User)ctx.Users.FindOneAs(typeof(User), Query.EQ("UserName", username));
                    if (_user != null)
                    {
                        _devices = _user.SnDeviceRegisted;
                        if (_devices == null)
                            _devices = new List<Device>();
                        list = _devices.ToList();
                        return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT.SUCCESS;
                    }
                    else
                        return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT.DO_NOT_EXIST;
                }
            }
            catch (Exception ex)
            {
                _messageSystemError = BaseCommon.ExeptionUtils.ExceptionToMessage(ex);
                return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT.SYSTEM_ERROR;
            }
            
        }

        public Device GetDeviceByImei(string deviceImei, string userId)
        {
            if (string.IsNullOrEmpty(deviceImei))
                throw new ArgumentNullException("DeviceImei", "Device Imei is not found!");
            if(string.IsNullOrEmpty(userId))
                throw new ArgumentNullException("UserId", "User Id is null!");
            var _user = (User)ctx.Users.FindOneAs(typeof(User), Query.EQ("_id", userId));
            var _dv = _user.SnDeviceRegisted.Find(d => d.Imei1.Equals(deviceImei));
            if (_dv == null)
                _dv = _user.SnDeviceRegisted.Find(d => d.Imei2.Equals(deviceImei));
            return _dv;    
        }

        public BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT GetDeviceByImei(string deviceImei, string userId, ref string _messageSystemError, ref Device device)
        {
            try
            {
                if (SafeSystemContext.ServerIsDown)
                    throw new ExeptionUtils.CustomException(BaseCommon.MSG_STR.AUTH_MESSAGE_STRING.SERVER_IS_DOWN);
                if (string.IsNullOrEmpty(deviceImei))
                    throw new ArgumentNullException("DeviceImei", "Device Imei is not found!");
                if (string.IsNullOrEmpty(userId))
                    throw new ArgumentNullException("UserId", "User Id is null!");
                var _user = (User)ctx.Users.FindOneAs(typeof(User), Query.EQ("_id", userId));
                var _dv = _user.SnDeviceRegisted.Find(d => d.Imei1.Equals(deviceImei));
                if (_dv == null)                
                    _dv = _user.SnDeviceRegisted.Find(d => d.Imei2.Equals(deviceImei));
                if (_dv != null)
                {
                    device = _dv;
                    return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT.SUCCESS;
                }
                else
                {
                    return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT.DO_NOT_EXIST;
                }
            }
            catch (Exception ex)
            {
                _messageSystemError = BaseCommon.ExeptionUtils.ExceptionToMessage(ex);
                return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT.SYSTEM_ERROR;
            }
        }

        public Device GetDeviceBySerialNumber(string sn, string userId)
        {
            if (string.IsNullOrEmpty(sn))
                throw new ArgumentNullException("Serial Number", "Device Serial Number is not found!");
            if (string.IsNullOrEmpty(userId))
                throw new ArgumentNullException("UserId", "User Id is null!");
            var _user = (User)ctx.Users.FindOneAs(typeof(User), Query.EQ("_id", userId));
            if (_user.SnDeviceRegisted == null)
                _user.SnDeviceRegisted = new List<Device>();
            var _dv = _user.SnDeviceRegisted.Find(d => d.Sn.Equals(sn));
            if (_dv == null)
                return null;
            return _dv;
        }

        public BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT GetDeviceBySerialNumber(string sn, string userId, ref string _messageSystemError, ref Device device)
        {
            try
            {
                if (SafeSystemContext.ServerIsDown)
                    throw new ExeptionUtils.CustomException(BaseCommon.MSG_STR.AUTH_MESSAGE_STRING.SERVER_IS_DOWN);
                if (string.IsNullOrEmpty(sn))
                    throw new ArgumentNullException("Serial Number", "Device Serial Number is not found!");
                if (string.IsNullOrEmpty(userId))
                    throw new ArgumentNullException("UserId", "User Id is null!");
                var _user = (User)ctx.Users.FindOneAs(typeof(User), Query.EQ("_id", userId));
                if (_user.SnDeviceRegisted == null)
                    _user.SnDeviceRegisted = new List<Device>();
                var _dv = _user.SnDeviceRegisted.Find(d => d.Sn.Equals(sn));
                if (_dv != null)
                {
                    device = _dv;
                    return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT.SUCCESS;
                }
                else
                    return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT.DO_NOT_EXIST;                
            }
            catch (Exception ex)
            {
                _messageSystemError = BaseCommon.ExeptionUtils.ExceptionToMessage(ex);
                return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT.SYSTEM_ERROR;
            }
        }

        public Device GetDeviceById(string deviceId, string userId)
        {
            if (string.IsNullOrEmpty(deviceId))
                return null;
                //throw new ArgumentNullException("Device Id", "Device Id is not found!");
            if (string.IsNullOrEmpty(userId))
                throw new ArgumentNullException("UserId", "User Id is null!");
            var _user = (User)ctx.Users.FindOneAs(typeof(User), Query.EQ("_id", userId));
            if (_user.SnDeviceRegisted == null)
                _user.SnDeviceRegisted = new List<Device>();
            var _dv = _user.SnDeviceRegisted.Find(d => d.Id.Equals(deviceId));
            return _dv;
        }   

        public BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_GET_BY_ID GetDeviceById(string deviceId, string userId, ref string _messageSystemError, ref Device device)
        {
            try
            {
                if (SafeSystemContext.ServerIsDown)
                    throw new ExeptionUtils.CustomException(BaseCommon.MSG_STR.AUTH_MESSAGE_STRING.SERVER_IS_DOWN);
                if (string.IsNullOrEmpty(deviceId))                    
                    throw new ArgumentNullException("Device Id", "Device Id is not found!");
                if (string.IsNullOrEmpty(userId))
                    throw new ArgumentNullException("UserId", "User Id is null!");
                var _user = (User)ctx.Users.FindOneAs(typeof(User), Query.EQ("_id", userId));
                if (_user.SnDeviceRegisted == null)
                    _user.SnDeviceRegisted = new List<Device>();
                var _dv = (Device)_user.SnDeviceRegisted.Find(d => d.Id.Equals(deviceId));
                if (_dv != null)
                {
                    device = _dv;
                    return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_GET_BY_ID.SUCCESS;
                }
                else
                    return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_GET_BY_ID.DO_NOT_EXIST;
            }
            catch (Exception ex)
            {
                _messageSystemError = BaseCommon.ExeptionUtils.ExceptionToMessage(ex);
                return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_GET_BY_ID.SYSTEM_ERROR;
            }
        }

        public Device GetDeviceByUserName(string deviceId, string userName)
        {
            if (string.IsNullOrEmpty(deviceId))
                return null;
                //    throw new ArgumentNullException("Device Id", "Device Id is not found!");
            if (string.IsNullOrEmpty(userName))
                throw new ArgumentNullException("User Name", "User Name is null!");
            var _user = (User)ctx.Users.FindOneAs(typeof(User), Query.EQ("UserName", userName));
            if (_user != null)
            {
                if (_user.SnDeviceRegisted == null)
                    _user.SnDeviceRegisted = new List<Device>();
                var _dv = _user.SnDeviceRegisted.Find(d => d.Id.Equals(deviceId));
                return _dv;
            }
            else
                return null;
        }

        public BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT GetDeviceByUserName(string deviceId, string userName, ref string _messageSystemError, ref Device device)
        {
            try
            {
                if (SafeSystemContext.ServerIsDown)
                    throw new ExeptionUtils.CustomException(BaseCommon.MSG_STR.AUTH_MESSAGE_STRING.SERVER_IS_DOWN);
                if (string.IsNullOrEmpty(deviceId))                    
                    throw new ArgumentNullException("Device Id", "Device Id is not found!");
                if (string.IsNullOrEmpty(userName))
                    throw new ArgumentNullException("User Name", "User Name is null!");
                var _user = (User)ctx.Users.FindOneAs(typeof(User), Query.EQ("UserName", userName));
                if (_user.SnDeviceRegisted == null)
                    _user.SnDeviceRegisted = new List<Device>();
                var _dv = (Device)_user.SnDeviceRegisted.Find(d => d.Id.Equals(deviceId));
                if (_dv != null)
                {
                    device = _dv;
                    return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT.SUCCESS;
                }
                else
                    return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT.DO_NOT_EXIST;
            }
            catch(Exception ex)
            {
                _messageSystemError = BaseCommon.ExeptionUtils.ExceptionToMessage(ex);
                return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT.SYSTEM_ERROR;
            }
        }

        public bool UpdateDeviceByDeviceId(string deviceId, Device dv, string userName)
        {
            if (string.IsNullOrEmpty(deviceId))
                return false;
            if (string.IsNullOrEmpty(userName))
                return false;           
            
            var _user = (User)ctx.Users.FindOneAs(typeof(User), Query.EQ("UserName", userName));
            if (_user != null)
            {
                if (_user.SnDeviceRegisted.Find(d => d.Id.Equals(dv.Id.ToString())) != null)
                {
                    //_user.SnDeviceRegisted[0].LocationTracking = new List<Location>();
                    //_user.SnDeviceRegisted[0].LocationTracking.Add(_lc);
                    // ctx.Users.Find(Query.EQ("SnDeviceRegisted._id", dv.Id)).Collection.Update(Query.EQ("SnDeviceRegisted._id", dv.Id),MongoDB.Driver.Builders.Update.PushWrapped("SnDeviceRegisted.$.LocationTracking",_lc));
    
                    ctx.Users.Update(Query.EQ("SnDeviceRegisted._id", dv.Id), MongoDB.Driver.Builders.Update.Set("SnDeviceRegisted.$", BsonDocumentWrapper.Create<Device>(dv)), UpdateFlags.Multi);                                       
                    return true;
                }
                else
                    return false;
            }
            else
                return false;           
           
        }

        public BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_UPDATE UpdateDeviceByDeviceId(string deviceId, Device dv, string userName, ref string _messageSystemError)
        {
            try
            {
                if (SafeSystemContext.ServerIsDown)
                    throw new ExeptionUtils.CustomException(BaseCommon.MSG_STR.AUTH_MESSAGE_STRING.SERVER_IS_DOWN);
                if (string.IsNullOrEmpty(deviceId))
                    throw new ArgumentNullException("DeviceId", "Device Id is null!");
                if (string.IsNullOrEmpty(userName))
                    throw new ArgumentNullException("UserName", "UserName is null!");

                var _user = (User)ctx.Users.FindOneAs(typeof(User), Query.EQ("UserName", userName));
                if (_user != null)
                {
                    if (_user.SnDeviceRegisted.Find(d => d.Id.Equals(dv.Id.ToString())) != null)
                    {                     
                        ctx.Users.Update(Query.EQ("SnDeviceRegisted._id", dv.Id), MongoDB.Driver.Builders.Update.Set("SnDeviceRegisted.$", BsonDocumentWrapper.Create<Device>(dv)), UpdateFlags.Multi);
                        return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_UPDATE.SUCCESS;
                    }
                    else
                        return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_UPDATE.EXIT_DATA;
                }
                return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_UPDATE.SUCCESS;
            }
            catch (Exception ex)
            {
                _messageSystemError = BaseCommon.ExeptionUtils.ExceptionToMessage(ex);
                return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_UPDATE.SYSTEM_ERROR;
            }

        }

        public bool CheckExpireDevice(string deviceId, string userId)
        {
            if (string.IsNullOrEmpty(deviceId))
                throw new ArgumentNullException("DeviceId", "Device Id is null!");
            var _user = (User)ctx.Users.FindOneAs(typeof(User), Query.EQ("_id", userId));
            if (_user.SnDeviceRegisted == null)
            {
                _user.SnDeviceRegisted = new List<Device>();
                throw new ExeptionUtils.CustomException("Không tìm thấy thiết bị yêu cầu.");
            }
            else
            {
                var _dv = _user.SnDeviceRegisted.Find(d => d.Id.Equals(deviceId));
                if (_dv.ExpireDate >= DateTime.UtcNow)
                    return true;
                else
                    return false;
            }
            
        }

        public BaseCommon.ERROR_CODE.ERROR_CODE_DEVICES_EXPIRE CheckExpireDevice(string deviceId, string userId, ref string _messageSystemError)
        {
            try
            {
                if (SafeSystemContext.ServerIsDown)
                    throw new ExeptionUtils.CustomException(BaseCommon.MSG_STR.AUTH_MESSAGE_STRING.SERVER_IS_DOWN);
                if (string.IsNullOrEmpty(deviceId))
                    throw new ArgumentNullException("DeviceId", "Device Id is null!");
                var _user = (User)ctx.Users.FindOneAs(typeof(User), Query.EQ("_id", userId));
                if (_user.SnDeviceRegisted == null)
                {
                    _user.SnDeviceRegisted = new List<Device>();
                    throw new ExeptionUtils.CustomException("Không tìm thấy thiết bị yêu cầu.");
                }
                else
                {
                    var _dv = _user.SnDeviceRegisted.Find(d => d.Id.Equals(deviceId));
                    if (_dv.ExpireDate >= DateTime.UtcNow)
                        return BaseCommon.ERROR_CODE.ERROR_CODE_DEVICES_EXPIRE.SUCCESS;
                    else                    
                        return BaseCommon.ERROR_CODE.ERROR_CODE_DEVICES_EXPIRE.EXPIRED;                
                }
            }
            catch (Exception ex)
            {
                _messageSystemError = BaseCommon.ExeptionUtils.ExceptionToMessage(ex);
                return BaseCommon.ERROR_CODE.ERROR_CODE_DEVICES_EXPIRE.SYSTEM_ERROR;
            }

        }

        #endregion

        #region History

        public IEnumerable<History> GetAllHistoryByUser(string userId)
        {
            List<History> _his = new List<History>();
            using (ctx.Database.Server.RequestStart(ctx.Database))
            {
                var his = ctx.History.FindAs(typeof(History), Query.EQ("UserID", userId));
                if (his.Count() > 0)
                    foreach (History dv in his)
                        _his.Add(dv);
                return _his;
            }
        }

        public BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT GetAllHistoryByUser(string userId, ref string _messageSystemError, ref  IEnumerable<History> list)
        {
            try
            {
                if (SafeSystemContext.ServerIsDown)
                    throw new ExeptionUtils.CustomException(BaseCommon.MSG_STR.AUTH_MESSAGE_STRING.SERVER_IS_DOWN);
                List<History> _his = new List<History>();
                using (ctx.Database.Server.RequestStart(ctx.Database))
                {
                    var his = ctx.History.FindAs(typeof(History), Query.EQ("UserID", userId));
                    if (his.Count() > 0)
                        foreach (History dv in his)
                            _his.Add(dv);
                    list = _his.ToList();
                    return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT.SUCCESS;
                }
            }
            catch (Exception ex)
            {
                _messageSystemError = BaseCommon.ExeptionUtils.ExceptionToMessage(ex);
                return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT.SYSTEM_ERROR;
            }
        }

        public History AddNewHistory(History his)
        {
            ctx.History.Insert(his);
            return his;
        }

        #endregion
        
        #region Roles       

        public IEnumerable<Roles> GetAllRoles()
        {
            List<Roles> _rolesList = new List<Roles>();
            if (SafeSystemContext.ServerIsDown)
                return null;
            var _roles = ctx.Roles.FindAs(typeof(Roles), Query.NE("Id", "null"));
            if (_roles.Count() > 0)
            {
                _rolesList.Clear();
                foreach (Roles r in _roles)
                    _rolesList.Add(r);
            }
            var result = userList.AsQueryable();
            return _rolesList;
        }

        public BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT GetAllRoles(ref string _messageSystemError, ref IEnumerable<Roles> list)
        {
            try
            {
                if (SafeSystemContext.ServerIsDown)
                    throw new ExeptionUtils.CustomException(BaseCommon.MSG_STR.AUTH_MESSAGE_STRING.SERVER_IS_DOWN);
                List<Roles> _rolesList = new List<Roles>();                
                var _roles = ctx.Roles.FindAs(typeof(Roles), Query.NE("Id", "null"));
                if (_roles.Count() > 0)
                {
                    _rolesList.Clear();
                    foreach (Roles r in _roles)
                        _rolesList.Add(r);
                }
                var result = userList.AsQueryable();
                list = _rolesList.ToList();
                return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT.SUCCESS;
            }
            catch (Exception ex)
            {
                _messageSystemError = BaseCommon.ExeptionUtils.ExceptionToMessage(ex);
                return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT.SYSTEM_ERROR;
            }
        }

        public string GetRoleNameById(string roleId)
        {
            var _role = (Roles)ctx.Roles.FindOneAs(typeof(Roles), Query.EQ("Id",roleId));
            if(_role != null)
                return _role.RoleName;
            else
                throw new ArgumentNullException("Role", "Get Role by Id Error.!");
        }

        public BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT GetRoleNameById(string roleId, ref string _messageSystemError, ref string roleName)
        {
            try
            {
                if (SafeSystemContext.ServerIsDown)
                    throw new ExeptionUtils.CustomException(BaseCommon.MSG_STR.AUTH_MESSAGE_STRING.SERVER_IS_DOWN);
                var _role = (Roles)ctx.Roles.FindOneAs(typeof(Roles), Query.EQ("Id", roleId));
                if (_role != null)
                {
                    roleName = _role.RoleName.ToString();
                    return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT.SUCCESS;
                }
                else
                    throw new ArgumentNullException("Role", "Get Role by Id Error.!");
            }
            catch (Exception ex)
            {
                _messageSystemError = BaseCommon.ExeptionUtils.ExceptionToMessage(ex);
                return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT.SYSTEM_ERROR;
            }
        }

        public  Roles GetRoleById(string roleId)
        {
            var _role = (Roles)ctx.Roles.FindOneAs(typeof(Roles), Query.EQ("Id", roleId));
            if (_role != null)
                return _role;
            else
                throw new ArgumentNullException("Role", "Get Role by Id Error.!");
        }

        public BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT GetRoleById(string roleId, ref string _messageSystemError, ref Roles role)
        {
            try
            {
                if (SafeSystemContext.ServerIsDown)
                    throw new ExeptionUtils.CustomException(BaseCommon.MSG_STR.AUTH_MESSAGE_STRING.SERVER_IS_DOWN);
                var _role = (Roles)ctx.Roles.FindOneAs(typeof(Roles), Query.EQ("Id", roleId));
                if (_role != null)
                {
                    role = _role;
                    return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT.SUCCESS;
                }
                else
                    throw new ArgumentNullException("Role", "Get Role by Id Error.!");
            }
            catch (Exception ex)
            {
                _messageSystemError = BaseCommon.ExeptionUtils.ExceptionToMessage(ex);
                return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT.SYSTEM_ERROR;
            }
        }
        
        public bool AddNewRole(string roleName)
        {
            var _role = ctx.Roles.FindAs(typeof(Roles), Query.EQ("RoleName", roleName));
            if (_role.Count() > 0)
            {
                throw new ArgumentNullException("Role Name", "The Role existed.!");

            }
            else
            {
                Roles newRole = new Roles();
                newRole.Id = Guid.NewGuid().ToString();
                newRole.RoleName = roleName; 
                newRole.Status = DBEntity.ObjectStatus.Active;
                newRole.LastUpdateBy = "1";
                newRole.LastUpdateDate = DateTime.UtcNow;
                newRole.CreateBy = "1";
                newRole.CreateDate = DateTime.UtcNow;
                ctx.Roles.Save(newRole);
                return true;
            }
        }

        public BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT AddNewRole(string roleName, ref string _messageSystemError)
        {
            try
            {
                if (SafeSystemContext.ServerIsDown)
                    throw new ExeptionUtils.CustomException(BaseCommon.MSG_STR.AUTH_MESSAGE_STRING.SERVER_IS_DOWN);
                var _role = ctx.Roles.FindAs(typeof(Roles), Query.EQ("RoleName", roleName));
                if (_role.Count() > 0)
                {
                    throw new ArgumentNullException("Role Name", "The Role existed.!");

                }
                else
                {
                    Roles newRole = new Roles();
                    newRole.Id = Guid.NewGuid().ToString();
                    newRole.RoleName = roleName;
                    newRole.Status = DBEntity.ObjectStatus.Active;
                    newRole.LastUpdateBy = "1";
                    newRole.LastUpdateDate = DateTime.UtcNow;
                    newRole.CreateBy = "1";
                    newRole.CreateDate = DateTime.UtcNow;
                    ctx.Roles.Save(newRole);
                    return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT.SUCCESS;
                }
            }
            catch (Exception ex)
            {
                _messageSystemError = BaseCommon.ExeptionUtils.ExceptionToMessage(ex);
                return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT.SYSTEM_ERROR;
            }
        }

        #endregion

        #region UserInRoles
        
        public IEnumerable<Roles> GetRolesByUser(string userId)
        {
            List<Roles> _roles = new List<Roles>();
            using (ctx.Database.Server.RequestStart(ctx.Database))
            {
                var _user = (User)ctx.Users.FindOneAs(typeof(User), Query.EQ("_id", userId));
                foreach (Roles r in _user.UserInRoles)
                {                    
                    var _role = (Roles)ctx.Roles.FindOneAs(typeof(Roles), Query.EQ("Id", r.Id));
                    _roles.Add(_role);
                }
                return _roles;   
            }
        }      

        public BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT GetRolesByUser(string userId, ref string _messageSystemError, ref IEnumerable<Roles> list)
        {            
            try
            {
                if(SafeSystemContext.ServerIsDown)
                    throw new ExeptionUtils.CustomException(BaseCommon.MSG_STR.AUTH_MESSAGE_STRING.SERVER_IS_DOWN);
                List<Roles> _roles = new List<Roles>();
                using (ctx.Database.Server.RequestStart(ctx.Database))
                {
                    var _user = (User)ctx.Users.FindOneAs(typeof(User), Query.EQ("_id", userId));
                    foreach (Roles r in _user.UserInRoles)
                    {
                        var _role = (Roles)ctx.Roles.FindOneAs(typeof(Roles), Query.EQ("Id", r.Id));
                        _roles.Add(_role);
                    }
                    list =  _roles.ToList();
                    return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT.SUCCESS;
                }
            }
            catch(Exception ex)
            {
                _messageSystemError = BaseCommon.ExeptionUtils.ExceptionToMessage(ex);
                return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT.SYSTEM_ERROR;
            }
        }
        
        public bool AddNewRoleForUser(string userId,string roleId)
        {
            var _user = (User)ctx.Users.FindOneAs(typeof(User), Query.EQ("_id", userId));
            if (_user == null)
                return false;
            //throw new ArgumentNullException("User", "The User does not exist.!");
            else
            {
                var _role = _user.UserInRoles.Exists(r => r.Id == roleId);
                if (_role)
                {
                    throw new ArgumentNullException("Role Name", "The Role existed for this user.!");
                }
                else
                {
                    var role = (Roles)ctx.Roles.FindOneAs(typeof(Roles), Query.EQ("Id", roleId));
                    if (role != null)
                    {
                        Roles newRole = new Roles();
                        newRole.Id = role.Id;
                        newRole.RoleName = role.RoleName;
                        newRole.Status = DBEntity.ObjectStatus.Active;
                        role.LastUpdateBy = "1";
                        role.LastUpdateDate = DateTime.UtcNow;
                        role.CreateBy = "1";
                        role.CreateDate = DateTime.UtcNow;
                        _user.UserInRoles.Add(role);
                        return true;
                    }
                    else
                    {
                        throw new ArgumentNullException("Add new role", "System error.!");
                    }
                }

            }
        }

        public BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT AddNewRoleForUser(string userId, string roleId,  ref string _messageSystemError )
        {
            try
            {
                if (SafeSystemContext.ServerIsDown)
                    throw new ExeptionUtils.CustomException(BaseCommon.MSG_STR.AUTH_MESSAGE_STRING.SERVER_IS_DOWN);
                var _user = (User)ctx.Users.FindOneAs(typeof(User), Query.EQ("_id", userId));
                if (_user == null)
                    throw new ArgumentNullException("User", "The User does not exist.!");
                else
                {
                    var _role = _user.UserInRoles.Exists(r => r.Id == roleId);
                    if (_role)
                    {
                        throw new ArgumentNullException("Role Name", "The Role existed for this user.!");
                    }
                    else
                    {
                        var role = (Roles)ctx.Roles.FindOneAs(typeof(Roles), Query.EQ("Id", roleId));
                        if (role != null)
                        {
                            Roles newRole = new Roles();
                            newRole.Id = role.Id;
                            newRole.RoleName = role.RoleName;
                            newRole.Status = DBEntity.ObjectStatus.Active;
                            role.LastUpdateBy = "1";
                            role.LastUpdateDate = DateTime.UtcNow;
                            role.CreateBy = "1";
                            role.CreateDate = DateTime.UtcNow;
                            if (_user.UserInRoles == null)
                                _user.UserInRoles = new List<Roles>();
                            _user.UserInRoles.Add(role);
                            return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT.SUCCESS;
                        }
                        else
                        {
                            throw new ArgumentNullException("Add new role", "System error.!");
                        }
                    }

                }
            }
            catch(Exception ex)
            {
                _messageSystemError = BaseCommon.ExeptionUtils.ExceptionToMessage(ex);
                return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT.SYSTEM_ERROR;
            }
            
        }

        #endregion
        
        #region Find/Search
        /// <summary> tìm kiếm tự do nguoi dung </summary>
        public static  BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT Search(string value, ref string _messageSystemError, ref List<User> list)
        {
            if (string.IsNullOrEmpty(value))
                return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT.SYSTEM_ERROR; 
            SafeSystemContext context = null;            
            try
            {
                list.Clear();
                context = new SafeSystemContext();
                //var query = from u in context.Users.AsQueryable<User>()
                //            where u.UserStatus != DBEntity.UserStatus.Deactivated &&
                //            (string.IsNullOrEmpty(value) || u.Id.Contains(value)
                //            || u.UserName.Contains(value)
                //            || u.UserType.ToString().Contains(value)
                //            || u.Age.ToString().Contains(value))                         
                //            select u;
                var query = from u in context.Users.AsQueryable<User>()
                            where u.UserStatus != DBEntity.UserStatus.Deactivated &&
                                (u.UserName.Contains(value) || u.Id.Contains(value))                         
                            select u;
                list = query.ToList();
                return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT.SUCCESS;
            }
            catch (Exception ex)
            {
                _messageSystemError = BaseCommon.ExeptionUtils.ExceptionToMessage(ex);
                return BaseCommon.ERROR_CODE.ERROR_CODE_ITEMS_SELECT.SYSTEM_ERROR;
            }
            finally
            {
                context = null;
               // GC.Collect();
            }
        }

        #endregion

        #region AndroidGCMPushNotification

        public bool RegistrationID(string deviceId, string userName, string regID)
        {

            // Upload the registration ID to your own server
            // The request to your server should be authenticated if your app is using accounts.       

            Device dv = GetDeviceByUserName(deviceId, userName);
            if (dv != null)
            {
        

                dv.registrationId = regID;
                return UpdateDeviceByDeviceId(deviceId, dv, userName);
            }

            return false;
        }

        public bool UnRegistrationID(string deviceId, string userName, string registrationId)
        {

            // Upload the registration ID to your own server
            // The request to your server should be authenticated if your app is using accounts.
            Device dv = GetDeviceByUserName(deviceId, userName);
            if (dv != null)
            {
                dv.registrationId = "";
                return UpdateDeviceByDeviceId(deviceId, dv, userName);
            }

            return false;
        }

        public string SendNotification(string deviceId, string userName, string message)
        {

            string GoogleAppID = "gothic-span-86816";
            string registrationId ="";
            Device dv = GetDeviceByUserName(deviceId, userName);
            if (dv != null)
            {
                registrationId = dv.registrationId;
                var SENDER_ID = "1053392119953";
                var value = message;
                WebRequest tRequest;
                tRequest = WebRequest.Create("https://android.googleapis.com/gcm/send");
                tRequest.Method = "post";
                tRequest.ContentType = " application/x-www-form-urlencoded;charset=UTF-8";
                tRequest.Headers.Add(string.Format("Authorization: key={0}", GoogleAppID));

                tRequest.Headers.Add(string.Format("Sender: id={0}", SENDER_ID));

                string postData = "collapse_key=score_update&time_to_live=108 & delay_while_idle=1&data.message=" + value + "&data.time=" + System.DateTime.Now.ToString() + "registration_ids=" + deviceId + "";
                Console.WriteLine(postData);
                Byte[] byteArray = Encoding.UTF8.GetBytes(postData);
                tRequest.ContentLength = byteArray.Length;

                Stream dataStream = tRequest.GetRequestStream();
                dataStream.Write(byteArray, 0, byteArray.Length);
                dataStream.Close();

                WebResponse tResponse = tRequest.GetResponse();

                dataStream = tResponse.GetResponseStream();

                StreamReader tReader = new StreamReader(dataStream);

                String sResponseFromServer = tReader.ReadToEnd();

                tReader.Close();
                dataStream.Close();
                tResponse.Close();
                return sResponseFromServer;
            }
            return null;
        }

        public string PushNotification(string deviceId, string userName, string message)
        {

            string GoogleAppID = "gothic-span-86816";
            string Authorization= "AIzaSyDQEuVM7np86vVlabXTB5rEjpD_ZVMU8Eo";
            string registrationId = "";
            Device dv = GetDeviceByUserName(deviceId, userName);
            if (dv != null)
            {
                registrationId = dv.registrationId;
                String SENDER_ID = "1053392119953";
                var value = message;
                WebRequest tRequest;
                tRequest = WebRequest.Create("https://android.googleapis.com/gcm/send");
                tRequest.Method = "post";
                tRequest.ContentType = " application/x-www-form-urlencoded;charset=UTF-8";
                tRequest.Headers.Add(string.Format("Authorization: key={0}", GoogleAppID));

                tRequest.Headers.Add(string.Format("Sender: id={0}", Authorization));

                string postData = "collapse_key=score_update&time_to_live=108 & delay_while_idle=1&data.message=" + value + "&data.time=" + System.DateTime.Now.ToString() + "registration_ids=" + registrationId + "";
                Console.WriteLine(postData);
                Byte[] byteArray = Encoding.UTF8.GetBytes(postData);
                tRequest.ContentLength = byteArray.Length;

                Stream dataStream = tRequest.GetRequestStream();
                dataStream.Write(byteArray, 0, byteArray.Length);
                dataStream.Close();

                WebResponse tResponse = tRequest.GetResponse();

                dataStream = tResponse.GetResponseStream();

                StreamReader tReader = new StreamReader(dataStream);

                String sResponseFromServer = tReader.ReadToEnd();

                tReader.Close();
                dataStream.Close();
                tResponse.Close();
                return sResponseFromServer;
            }
            return null;
        }

        #endregion


    }
}